package com.md.common.utils.wechat;

import com.alibaba.fastjson.JSONObject;
import com.md.common.utils.HttpUtils;
import com.md.common.utils.json.JSONUtil;
import com.md.common.utils.wechat.exception.WxApiException;
import com.md.common.utils.wechat.model.WxAccessToken;
import com.md.common.utils.wechat.model.WxJsApiTicket;
import com.md.common.utils.wechat.model.WxOauthAccessToken;
import com.md.common.utils.wechat.model.WxUserInfo;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 功能描述：微信公众平台api代理
 *
 * @author lujianping@oak168.com
 * @version 1.0
 * @date 2018-7-17 10:13
 * @since JDK 1.8
 */
@Component("wechatMpApiProxy")
public class WechatMpApiProxy {
	private static final Logger LOGGER = LoggerFactory.getLogger(WechatMpApiProxy.class);

//    @Value("${wxmp.host}")
	private String host = "https://api.weixin.qq.com";
//    @Value("${wxmp.unifiedorder_url}")
	private String unifiedorder_url; // 统一下单URL
//    @Value("${wxmp.auth_access_token_url}")
	private String auth_access_token_url;
//    @Value("${wxmp.fwh_appId}")
	private String fwh_appId;
//    @Value("${wxmp.fwh_secret}")
	private String fwh_secret;

//    @Value("${wxmp.fwh_mechId}")
	private String fwh_mechId;
//    @Value("${wxmp.fwh_notifyUrl}")
	private String fwh_notifyUrl;
//    @Value("${wxmp.fwh_appSecret}")
	private String fwh_appSecret;
//    @Value("${wxmp.fwh_key}")
	private String fwh_key;

	public WxAccessToken getFwhAccessToken() throws WxApiException {
        String bizDesc = "获取服务号接口凭据";
        return getAccessToken(bizDesc, fwh_appId, fwh_secret);
    }

    public WxJsApiTicket getFwhJsApiTicket() throws WxApiException {
        String bizDesc = "获取服务号jsapi_ticket";
        WxAccessToken wxAccessToken = getFwhAccessToken();
        return getJsApiTicket(bizDesc, fwh_appId, fwh_secret, wxAccessToken.getAccess_token());
    }
    
    private WxAccessToken getAccessToken(String bizDesc, String appId, String secret) throws WxApiException {
        LOGGER.info("{}start", bizDesc);
        WxAccessToken wxAccessToken = null;
        StringBuilder sb = new StringBuilder();
        sb.append(host).append("/cgi-bin/token").append(String.format("?grant_type=client_credential&appid=%s&secret=%s", appId, secret));
        try {
            HttpResponse response = HttpUtils.doGet(sb.toString(), null);
            if (response .getStatusLine().getStatusCode() == 200) {
                String resJson = EntityUtils.toString(response.getEntity(), "UTF-8");
                JSONObject json = JSONObject.parseObject(resJson);
                if (!json.containsKey("errcode")) {
                    wxAccessToken = JSONUtil.toBean(resJson, WxAccessToken.class);
                } else {
                    LOGGER.error("{}失败, errorCode：{}", bizDesc, json.get("errcode").toString());
                    throw new WxApiException();
                }
            }
        } catch (Exception e) {
            LOGGER.error("{}异常", bizDesc, e);
            throw new WxApiException();
        }
        LOGGER.info("{}end", bizDesc);
        return wxAccessToken;
    }
    
    private WxJsApiTicket getJsApiTicket(String bizDesc, String appId, String secret, String accessToken) throws WxApiException {
        LOGGER.info("{}start", bizDesc);
        WxJsApiTicket wxJsApiTicket = null;
        StringBuilder sb = new StringBuilder();
        sb.append(host).append("/cgi-bin/ticket/getticket").append(String.format("?access_token=%s&type=jsapi", accessToken));
        try {
            HttpResponse response = HttpUtils.doGet(sb.toString(), null);
            if (response .getStatusLine().getStatusCode() == 200) {
                JSONObject json = JSONObject.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8"));
                Integer errcode = json.getInteger("errcode");
                if (errcode == 0) {
                	//{"errcode":0,"errmsg":"ok","ticket":"HoagFKDcsGMVCIY2vOjf9hlyTO5vj-2M6Qd163MbBP66NUhZQ1mfC3iPEI6k3IMVaIX_0DKcdoRzRVzFgNOTtg","expires_in":7200}"
                    String ticket = json.get("ticket").toString();
                    int expires_in = json.getInteger("expires_in");
                    wxJsApiTicket = new WxJsApiTicket();
                    wxJsApiTicket.setTicket(ticket);
                    wxJsApiTicket.setExpires_in(expires_in);
                } else {
                    LOGGER.error("{}失败, errorCode：{}, errorMsg：{}", bizDesc,json.get("errcode").toString(),json.get("errmsg").toString());
                    throw new WxApiException();
                }
            }
        } catch (Exception e) {
            LOGGER.error("{}异常", e);
            throw new WxApiException();
        }
        LOGGER.info("{}end", bizDesc);
        return wxJsApiTicket;
    }

    public WxOauthAccessToken getOauthAccessToken(String code) throws WxApiException {
        String bizDesc = "获取网页授权接口凭据";
        LOGGER.info("{}start", bizDesc);
        WxOauthAccessToken wxOauthAccessToken = null;
        StringBuilder sb = new StringBuilder();
        sb.append(host).append("/sns/oauth2/access_token").append(String.format("?appid=%s&secret=%s&code=%s&grant_type=authorization_code", fwh_appId, fwh_secret, code));
        try {
            HttpResponse response = HttpUtils.doGet(sb.toString(), null);
            if (response .getStatusLine().getStatusCode() == 200) {
                String resJson = EntityUtils.toString(response.getEntity(), "UTF-8");
                JSONObject json = JSONObject.parseObject(resJson);
                if (!json.containsKey("errcode")) {
                    wxOauthAccessToken = JSONUtil.toBean(resJson, WxOauthAccessToken.class);
                } else {
                    LOGGER.error("{}失败, errorCode：{}", json.get("errcode").toString());
                    throw new WxApiException();
                }
            }
        } catch (Exception e) {
            LOGGER.error("{}异常", e);
            throw new WxApiException();
        }
        LOGGER.info("{}end", bizDesc);
        return wxOauthAccessToken;
    }

    public WxUserInfo getWxUserInfo(String oauthAccessToken, String openId) throws WxApiException {
        String bizDesc = "网页授权获取微信用户信息";
        LOGGER.info("{}start", bizDesc);
        WxUserInfo wxUserInfo = null;
        StringBuilder sb = new StringBuilder();
        sb.append(host).append("/sns/userinfo").append(String.format("?access_token=%s&openid=%s&lang=zh_CN", oauthAccessToken, openId));
        try {
            HttpResponse response = HttpUtils.doGet(sb.toString(), null);
            if (response .getStatusLine().getStatusCode() == 200) {
                String resJson = EntityUtils.toString(response.getEntity(), "UTF-8");
                JSONObject json = JSONObject.parseObject(resJson);
                if (!json.containsKey("errcode")) {
                    wxUserInfo = JSONUtil.toBean(resJson, WxUserInfo.class);
                } else {
                    LOGGER.error("{}失败, errorCode：{}", json.get("errcode").toString());
                    throw new WxApiException();
                }
            }
        } catch (Exception e) {
            LOGGER.error("{}异常", e);
            throw new WxApiException();
        }
        LOGGER.info("{}end", bizDesc);
        return wxUserInfo;
    }
    
   /* public WxJsApiConfig getFwhJsApiConfig(String url) {
    	String bizDesc = "获取服务号JsApiCofnig";
		LOGGER.info("{}start", bizDesc);
		WxJsApiConfig config = new WxJsApiConfig();
		// 时间戳
		String timestamp = System.currentTimeMillis() + "";
		// 随机字符串
		String nonceStr = UUID.randomUUID().toString().replace("-", "");
		try {
			WxJsApiTicket wxJsApiTicket = getFwhJsApiTicket();
			String jsapi_ticket = wxJsApiTicket.getTicket();
			LOGGER.info("{}start,url:{},timestamp:{},nonceStr:{}", bizDesc, url, timestamp, nonceStr);
			Map<String, String> ret = WxUtil.sign(jsapi_ticket, url);
			config.setAppId(fwh_appId);
			config.setTimestamp(ret.get("timestamp"));
			config.setNonceStr(ret.get("nonceStr"));
			config.setSignature(ret.get("signature"));
			LOGGER.info("{}start,签名结果：{}", bizDesc, config.toString());
		} catch (Exception e) {
			LOGGER.error("{}异常", e);
			throw new WxApiException();
		}
		LOGGER.info("{}end", bizDesc);
		return config;
	}*/

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getFwh_appId() {
		return fwh_appId;
	}

	public void setFwh_appId(String fwh_appId) {
		this.fwh_appId = fwh_appId;
	}

	public String getFwh_secret() {
		return fwh_secret;
	}

	public void setFwh_secret(String fwh_secret) {
		this.fwh_secret = fwh_secret;
	}

	public String getFwh_mechId() {
		return fwh_mechId;
	}

	public void setFwh_mechId(String fwh_mechId) {
		this.fwh_mechId = fwh_mechId;
	}

	public String getFwh_notifyUrl() {
		return fwh_notifyUrl;
	}

	public void setFwh_notifyUrl(String fwh_notifyUrl) {
		this.fwh_notifyUrl = fwh_notifyUrl;
	}

	public String getFwh_appSecret() {
		return fwh_appSecret;
	}

	public void setFwh_appSecret(String fwh_appSecret) {
		this.fwh_appSecret = fwh_appSecret;
	}

	public String getFwh_key() {
		return fwh_key;
	}

	public void setFwh_key(String fwh_key) {
		this.fwh_key = fwh_key;
	}

	public String getUnifiedorder_url() {
		return unifiedorder_url;
	}

	public void setUnifiedorder_url(String unifiedorder_url) {
		this.unifiedorder_url = unifiedorder_url;
	}

	public String getAuth_access_token_url() {
		return auth_access_token_url;
	}

	public void setAuth_access_token_url(String auth_access_token_url) {
		this.auth_access_token_url = auth_access_token_url;
	}

}
